<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Menu;
use App\Models\Role;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Hash;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Tymon\JWTAuth\Exceptions\JWTException;

class AuthController extends Controller
{
    /**
     * 将扁平数组转换为树形结构并移除id和parentId字段
     *
     * @param array $items 包含id和parentId的二维数组
     * @param int $parentId 起始父ID（默认为0）
     * @param string $idKey ID字段名（默认为'id'）
     * @param string $parentKey 父ID字段名（默认为'parentId'）
     * @param string $childrenKey 子节点字段名（默认为'children'）
     * @return array 树形结构数组（不包含id和parentId）
     */
    private function buildTreeWithoutIds(array $items, $parentId = 0, $idKey = 'id', $parentKey = 'parentId', $childrenKey = 'children')
    {
        $branch = [];

        foreach ($items as $item) {
            if ($item[$parentKey] == $parentId) {
                // 复制当前项，排除id和parentId
                $newItem = $item;
                unset($newItem[$idKey], $newItem[$parentKey]);

                // 递归处理子项
                $children = $this->buildTreeWithoutIds($items, $item[$idKey], $idKey, $parentKey, $childrenKey);
                if ($children) {
                    $newItem[$childrenKey] = $children;
                }

                $branch[] = $newItem;
            }
        }

        return $branch;
    }

    /**
     * 合并并去重多维数组中的menuIds
     *
     * @param array $data 格式为 [{"menuIds": "1,2,3"}, {"menuIds": "3,4,5"}] 的数组
     * @return array 去重后的ID数组
     */
    private function mergeAndUniqueMenuIds(array $data): array
    {
        $allIds = [];

        foreach ($data as $item) {
            // 检查menuIds是否存在且不为null
            if (isset($item['menuIds']) && $item['menuIds'] !== null) {
                // 将字符串按逗号分割并转为数组
                $ids = explode(',', $item['menuIds']);

                // 过滤掉空字符串（处理可能的连续逗号或空值）
                $validIds = array_filter($ids, function ($id) {
                    return trim($id) !== '';
                });

                // 去除每个ID周围可能存在的空格并转为整数
                $cleanIds = array_map(function ($id) {
                    return (int)trim($id);
                }, $validIds);

                // 添加到总ID数组
                $allIds = array_merge($allIds, $cleanIds);
            }
        }

        // 去重并返回
        return array_values(array_unique($allIds));
    }

    private function filterRoutes(array $routes)
    {
        $data =  array_map(function ($item) {
            $itemData = [];

            $itemData['id'] = $item['id'];
            $itemData['parentId'] = $item['parentId'];
            $itemData['path'] = $item['path'];
            $itemData['name'] = $item['name'];
            if ($item['component']) {
                $itemData['component'] = $item['component'];
            }

            $itemData['meta'] = [];
            $itemData['meta']['title'] = $item['title'];

            if ($item['icon'] !== null) {
                $itemData['meta']['icon'] = $item['icon'];
            }

            if ($item['rank'] !== null) {
                $itemData['meta']['rank'] = $item['rank'];
            }

            if ($item['activePath'] !== null) {
                $itemData['meta']['activePath'] = $item['activePath'];
            }

            if ($item['auths'] !== null) {
                $itemData['meta']['auths'] = $item['auths'];
            }

            if ($item['enterTransition'] !== null) {
                $itemData['meta']['enterTransition'] = $item['enterTransition'];
            }

            if ($item['frameSrc'] !== null) {
                $itemData['meta']['frameSrc'] = $item['frameSrc'];
            }

            if ($item['leaveTransition'] !== null) {
                $itemData['meta']['leaveTransition'] = $item['leaveTransition'];
            }
            if ($item['redirect'] !== null) {
                $itemData['meta']['redirect'] = $item['redirect'];
            }

            $itemData['meta']['frameLoading'] = (bool)$item['frameLoading'];
            $itemData['meta']['keepAlive'] = (bool)$item['keepAlive'];
            $itemData['meta']['hiddenTag'] = (bool)$item['hiddenTag'];
            $itemData['meta']['fixedTag'] = (bool)$item['fixedTag'];
            $itemData['meta']['showLink'] = (bool)$item['showLink'];
            $itemData['meta']['showParent'] = (bool)$item['showParent'];
            $itemData['meta']['roles'] = ['admin'];

            return $itemData;
        }, $routes);

        return $this->buildTreeWithoutIds($data);
    }

    // 初始化账号
    public function init()
    {

        $user = User::where('username', 'admin')->first();

        if ($user) {
            return $this->success(message: '初始化成功', data: ['id' => $user->id]);
        }

        try {
            $result = User::create([
                'username' => 'admin',
                'password' => Hash::driver('bcrypt')->make('twl1358q.')
            ]);
            return $this->success(message: '初始化成功', data: ['id' => $result->id]);
        } catch (HttpException $error) {
            return $this->error(status: 500, data: $error);
        }
    }

    public function login(Request $request)
    {

        $body = $request->json()->all();

        $user = User::where('username', $body['username'])->first();

        if (!$user) {
            return $this->error(message: '账号不存在');
        }

        $isLogin = Hash::check($body['password'], $user->password);

        if (!$isLogin) {
            return $this->error(message: '账号或密码错误');
        }

        $token = JWTAuth::fromUser($user);

        $info = [];
        $info['accessToken'] = $token;
        $info['refreshToken'] = $token;
        $info['roles'] = ['admin'];

        /** 获取用户按钮权限 */
        if ($user->username === 'admin') {
            $info['permissions'] = ['*:*:*'];
        } else {

            $roleIds =  $user->roleIds;

            $roleIds = $roleIds ? array_map(function ($value) {
                return (int)$value;
            }, explode(',', $roleIds)) : [];

            $role = Role::select('menuIds')->whereIn('id', $roleIds)->get()->toArray();

            $roleMenuIds = $this->mergeAndUniqueMenuIds($role);

            $menuList = Menu::select('auths')->whereIn('id', $roleMenuIds)->where('menuType', 3)->get()->toArray();

            $info['permissions'] = $menuList ? array_map(function ($value) {
                return $value['auths'];
            }, $menuList) : [];
        }

        $info += $user->toArray();

        return $this->success(data: $info);
    }

    public function routes()
    {
        $menu = Menu::whereNot('menuType', 3)->get()->toArray();

        $routes = [];

        $user = JWTAuth::parseToken()->authenticate();

        if ($user->username ===  'admin') {
            $routes = $this->filterRoutes($menu);
        } else {
            $roleIds =  $user->roleIds;

            $roleIds = $roleIds ? array_map(function ($value) {
                return (int)$value;
            }, explode(',', $roleIds)) : [];

            $role = Role::select('menuIds')->whereIn('id', $roleIds)->get()->toArray();

            $roleMenuIds = $this->mergeAndUniqueMenuIds($role);

            $menuList = Menu::whereIn('id', $roleMenuIds)->whereNot('menuType', 3)->get()->toArray();

            $routes = $this->filterRoutes($menuList);
        }

        return $this->success(data: $routes);
    }

    public function logout()
    {
        try {
            // 清除token
            JWTAuth::invalidate(JWTAuth::getToken());
            return $this->success(message: '退出成功');
        } catch (JWTException $e) {
            return $this->error(status: 500, message: '退出失败，请稍后再试', data: $e->getMessage());
        }
    }
}
